#include "StdAfx.h"


SingletonManager::SingletonManager(void)
{
}
SingletonManager::~SingletonManager(void)
{
	if(PhysicsSDK)
		PhysicsSDK->release();
}
void SingletonManager::Init(HDC hdc)
{
	Reader reader(gMainConfigPath);
	BBVector<sptr<Binding>> bindings;
	//load main block
	bindings=reader.GetBindings("Main");
	//set main variables
	ConfigFolderPath=GetAux(bindings, "ConfigFolder");
	bool bEnableShaders=GetBool(bindings, "EnableShaders");
	//init the modules
	Graphics.bEnableShaders=bEnableShaders;
	Graphics.InitGL(hdc);
	InitContent();
	//Game.Init();
}
void SingletonManager::InitPhysics()
{
	PhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION, NULL, NULL);
	if(!PhysicsSDK)
	{
		_log("Failed to init PhysX SDK!");
		exit(0);
	}
	NxSceneDesc sceneDesc;
	sceneDesc.gravity.set(0,-98.1f,0);
	sceneDesc.userTriggerReport = &Sensor;
	_MAIN_SCENE=PhysicsSDK->createScene(sceneDesc);
	if(!_MAIN_SCENE)
	{
		_log("Failed to create a scene!");
		exit(0);
	}
	NxScene *scene=_MAIN_SCENE;
	
	NxMaterial *defaultMaterial = scene->getMaterialFromIndex(0);
	defaultMaterial->setRestitution(0.3f);
	defaultMaterial->setStaticFriction(0.5f);
	defaultMaterial->setDynamicFriction(0.5f);

	Graphics.FloorWidth=300;
	//bounding planes
	NxActorDesc actorDesc;
	//Ground plane
	NxPlaneShapeDesc planeDesc[5];
	planeDesc[0].normal = NxVec3(0,1,0);
	planeDesc[0].d = 0.0f;
	actorDesc.shapes.pushBack(&planeDesc[0]);
	//4 walls
	planeDesc[1].d=-Graphics.FloorWidth/2.0;
	planeDesc[1].normal=Vec3(1,0,0);
	actorDesc.shapes.pushBack(&planeDesc[1]);

	planeDesc[2].d=-Graphics.FloorWidth/2.0;
	planeDesc[2].normal=Vec3(-1,0,0);
	actorDesc.shapes.pushBack(&planeDesc[2]);

	planeDesc[3].d=-Graphics.FloorWidth/2.0;
	planeDesc[3].normal=Vec3(0,0,1);
	actorDesc.shapes.pushBack(&planeDesc[3]);

	planeDesc[4].d=-Graphics.FloorWidth/2.0;
	planeDesc[4].normal=Vec3(0,0,-1);
	actorDesc.shapes.pushBack(&planeDesc[4]);

	scene->createActor(actorDesc);
	_log("Successfully initialized physics");
}
NxPhysicsSDK* SingletonManager::GetPhysicsSDK()
{
	return PhysicsSDK;
}
void SingletonManager::InitContent()
{
	InitPhysics();
	Reader reader(gMainConfigPath);
	BBVector<sptr<Binding>> bindings;
	//load content block
	bindings=reader.GetBindings("Content");
	//set content specific variables
	Content.ConfigPath=ConfigFolderPath<<GetAux(bindings, "Config");
	Content.MeshesFolder=GetAux(bindings, "MeshesFolder");
	Content.TexturesFolder=GetAux(bindings, "TexturesFolder");
	Content.ShadersFolder=GetAux(bindings, "ShadersFolder");
	Content.MaterialsFolder=GetAux(bindings, "MaterialsFolder");
	Content.ModelsFolder=GetAux(bindings, "ModelsFolder");
	//load initial content
	Content.LoadContent();
	_log("Content succesfully loaded");
}
string SingletonManager::GetAux(BBVector<sptr<Binding>> &bindings, string name)
{
	string aux;
	try
	{
		aux=bindings.GetByName(name)->Aux;
	}
	catch(BException&)
	{
		_log("Bindings: Failed to load "<<name<<" binding.");
	}
	return aux;
}
bool SingletonManager::GetBool(BBVector<sptr<Binding>> &bindings, string name)
{
	string aux=GetAux(bindings, name);
	if(aux^string("true"))
		return true;
	else if(aux^string("false"))
		_log(bindings.Name<<": field '"<<name<<"' not set to true or false. Assuming false.");
	return false;
}
